package com.walle.ak47.commons.redis;

import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;

public class RedisQueue extends RedisList {
	 
    public RedisQueue(JedisPool pool, String key) {
        super(pool, key);
    }

    /**
     * 加入一个或多个值
     *
     * @param direction 方向
     * @param values    要加入的值
     *
     * @return 队列的新长度
     */
    public long push( Direction direction, String... values) {
        if (direction == Direction.Left) {
            return pool.getResource().lpush(key, values);
        } else {
            return pool.getResource().rpush(key, values);
        }
    }
    
    /**
     * 读取并删除一个值
     *
     * @param direction 方向
     *
     * @return null 或队列中的值
     */
    public String pop(final Direction direction) {
        if (direction == Direction.Left) {
            return pool.getResource().lpop(key);
        } else {
            return pool.getResource().rpop(key);
        }
    }
    
    /**
     * 入队列  (已测试)
     * @param values
     * @return
     */
    public long push( String... values) 
    {
		long size = 0 ;
    	
    	boolean isBroken = false;
		Jedis jedis = null;
		try
		{
			jedis = pool.getResource() ;
			size = jedis.lpush(key, values);
		}catch (JedisException e) {
			isBroken = true;
			logger.warn("failed:push(" + values.toString() + ")" , e);
			throw e;
		} finally {
			release(jedis, isBroken);
		}
		
		return size ;
    }
    
    /**
     * 出队列  (已测试)
     * @return
     */
    public String pop() 
    {
    
    	String value ;
    	
    	boolean isBroken = false;
		Jedis jedis = null;
		try
		{
			jedis = pool.getResource() ;
			value = jedis.rpop(key);
		}catch (JedisException e) {
			isBroken = true;
			logger.warn("failed:pop()" , e);
			throw e;
		} finally {
			release(jedis, isBroken);
		}
		
		return value ;
    }
    

    /**
     * 阻塞式 pop
     *
     * @param direction 读取方向
     * @param timeout   超时秒数，0表示无限制
     *
     * @return null 或队列中的值
     */
    public String popBlocking(final Direction direction, final int timeout) {
            List<String> list;

            if (direction == Direction.Left) {
                list = pool.getResource().blpop(timeout, key);
            } else {
                list = pool.getResource().brpop(timeout, key);
            }

            if (list == null || list.isEmpty()) {
                return null;
            } else {
                return list.get(1);
            }
    }

    enum Direction {
        Left, Right
    }

}
